package com.jiaomatech.demo.order.aspect;

import com.alibaba.fastjson.JSON;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * Description: 服务统一异常处理 .<br>
 *
 * @author jm
 */
@ControllerAdvice
public class WebExceptionHandler {
    private final static Logger logger = LoggerFactory.getLogger(WebExceptionHandler.class);

    /**
     * 定义参数异常处理器.
     *
     * @param e 当前平台异常参数对象.
     * @return org.springframework.http.ResponseEntity
     */
    @ExceptionHandler(BindException.class)
    @ResponseBody
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public ResponseEntity<Map<String, Object>> validateErrorHandler(BindException e) {
        BindingResult bindingResult = e.getBindingResult();
        return new ResponseEntity<>(toErrorMap(bindingResult), HttpStatus.BAD_REQUEST);
    }

    /**
     * 定义参数异常处理器.
     *
     * @param e 当前平台异常参数对象.
     * @return org.springframework.http.ResponseEntity
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    @ResponseBody
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public ResponseEntity<Map<String, Object>> validateErrorHandler(MethodArgumentNotValidException e) {
        BindingResult bindingResult = e.getBindingResult();
        return new ResponseEntity<>(toErrorMap(bindingResult), HttpStatus.BAD_REQUEST);
    }

    /**
     * 转换格式.
     *
     * @param bindingResult
     * @return
     */
    private Map<String, Object> toErrorMap(BindingResult bindingResult) {
        Map<String, Object> errorMap = new HashMap<>(3);
        if (bindingResult.hasErrors()) {
            List<FieldError> errorList = bindingResult.getFieldErrors();
            List<String> errorMsg = errorList.stream().map(err -> {
                return "字段:" + err.getField() + "不合法，原因:" + err.getDefaultMessage();
            }).collect(Collectors.toList());
            errorMap.put("success", false);
            errorMap.put("message", errorMsg.get(0));
            errorMap.put("errorMsg", errorMsg);
            logger.error("参数不合法: {}", JSON.toJSONString(errorMsg));
        }
        return errorMap;
    }
}
